home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / comm / bbs / cit_src_AD08.lha / floors.c < prev    next >
C/C++ Source or Header  |  1998-05-10  |  20KB  |  945 lines

  1. /*
  2. *       Floors.c
  3. *
  4. * Floor handling code for Citadel-86.
  5. */
  6. #include "ctdl.h"
  7. /*
  8. *       Contents
  9. */
  10. char SelDirs = FALSE,
  11. SelShared    = FALSE,
  12. SelPriv      = FALSE,
  13. SelRO        = FALSE,
  14. SelNew       = FALSE,
  15. SelArch      = FALSE,
  16. SelAnon      = FALSE;
  17. char ShowNew;
  18. char NotForgotten = TRUE;
  19. char JustChecking;
  20. char HasSkipped;
  21. static char maim;
  22. char FoundNew;
  23. static int  GlobalFloor;
  24. static int  MoveCount;
  25. extern struct floor  *FloorTab;
  26. extern rTable    *roomTab;
  27. extern CONFIG    cfg;
  28. extern aRoom     roomBuf;
  29. extern logBuffer logBuf;
  30. extern MessageBuffer   msgBuf;
  31. extern char      remoteSysop;
  32. extern int       thisRoom;
  33. extern char      loggedIn;       /* Are we logged in?            */
  34. extern int       TopFloor;
  35. extern char      *confirm;
  36. extern char      outFlag;
  37. extern char      onConsole;
  38. extern char      *baseRoom;
  39. static int FlagCheck(int i);
  40. int FindFloor(label name, char doPartial);
  41. /*
  42. * FloorRunner()
  43. *
  44. * This function runs through all the rooms on a floor, applying the given
  45. * function to all rooms on that floor.
  46. */
  47. int FloorRunner(int start, int (*func)(int r))
  48.   {
  49.   int rover, CurrentFloor;
  50.   if (start == ERROR) return ERROR;
  51.   CurrentFloor = roomTab[start].rtFlIndex;
  52.   if (!FloorTab[CurrentFloor].FlInuse)
  53.   CurrentFloor = 0;
  54.   /* start with current room, go through table */
  55.   for (rover = 0; rover < MAXROOMS; rover++)
  56.     {
  57.     /* deep breath ... should rewrite this, prime example of
  58.     programming via accretion. */
  59.     if (!FloorTab[roomTab[rover].rtFlIndex].FlInuse)
  60.     roomTab[rover].rtFlIndex = 0;
  61.     if ( roomTab[rover].rtFlIndex == CurrentFloor && (KnownRoom(rover) ||
  62.     (NotForgotten && roomTab[rover].rtflags.INUSE &&
  63.     (aide && (cfg.BoolFlags.aideSeeAll || onConsole) &&
  64.     (!roomTab[rover].rtflags.INVITE || SomeSysop())))))
  65.       {
  66.       if ((*func)(rover)) return rover;
  67.  
  68.       }
  69.  
  70.     }
  71.   return ERROR;
  72.  
  73.   }
  74. /*
  75. * NewRoom()
  76. *
  77. * This function gets next new room in system (like GotoRoom()) on the current
  78. * floor.
  79. */
  80. int NewRoom()
  81.   {
  82.   int CurrentFloor, OldFloor, roomNo;
  83.   OldFloor = thisFloor;
  84.   CurrentFloor = -1;
  85.   while (   (roomNo = FloorRunner(thisRoom, NSRoomHasNew)) == ERROR &&
  86.   CurrentFloor != TopFloor     )
  87.     {
  88.     thisRoom = FirstRoom(++CurrentFloor);
  89.  
  90.     }
  91.   if (CurrentFloor == TopFloor)
  92.   roomNo = 0;           /* no new-message rooms found */
  93.   getRoom(roomNo);
  94.   mPrintf("%s\n ", roomBuf.rbname);
  95.   /* really ugly kludge.  someday locate this gunk in gotoRoom() */
  96.   if (!KnownRoom(thisRoom))
  97.     {
  98.     SetKnown(0, MAXVISIT - 1, thisRoom, &logBuf);
  99.  
  100.     }
  101.   return !(OldFloor == roomTab[thisRoom].rtFlIndex);
  102.  
  103.   }
  104. /*
  105. * FirstRoom()
  106. *
  107. * This function gets the first room on the specified floor.
  108. */
  109. int FirstRoom(int FloorNo)
  110.   {
  111.   int rover;
  112.   for (rover = 0; rover < MAXROOMS; rover++)
  113.     {
  114.     if (     roomTab[rover].rtflags.INUSE &&
  115.     roomTab[rover].rtFlIndex == FloorNo    )
  116.     return rover;
  117.  
  118.     }
  119.   return ERROR;
  120.  
  121.   }
  122. /*
  123. * DoFloor()
  124. *
  125. * This function handles the fanout for floor commands.
  126. */
  127. int DoFloors()
  128.   {
  129.   int  toReturn;
  130.   char again, c[2];
  131.   char *FloorOpts[] =
  132.     {
  133.     TERM "Aide", TERM "Z\bForget", TERM "Skip",
  134.     TERM "Goto", TERM "Known Floors", TERM "C\b", ""
  135.  
  136.     };
  137.   SListBase  FSelects =
  138.     {
  139.     NULL, FindSelect, NULL, NoFree, NULL
  140.  
  141.     };
  142.   do
  143.     {
  144.     toReturn = GOOD_SELECT;
  145.     if (CmdMenuList(FloorOpts, &FSelects, "floor.mnu", c, TRUE, FALSE)
  146.     == BACKED_OUT) return GOOD_SELECT;
  147.     again = FALSE;
  148.     switch (c[0])
  149.       {
  150.       case 'A': toReturn = FAide();     break;
  151.       case 'Z': toReturn = FForget();     break;
  152.       case 'S':
  153.       case 'G': toReturn = FGotoSkip(c[0]);   break;
  154.       case 'K': toReturn = FKnown(ONLY_FLOORS);   break;
  155.       case 'C': toReturn = FConfigure();      break;
  156.       default:
  157.       ;
  158.  
  159.       }
  160.     if (toReturn == BACKED_OUT)
  161.       {
  162.       again = TRUE;
  163.       PushBack('\b');
  164.  
  165.       }
  166.  
  167.     }
  168.   while (again);
  169.   return toReturn;
  170.  
  171.   }
  172. /*
  173. * FInvite()
  174. *
  175. * This function is used to invite a user to all rooms on a floor.
  176. */
  177. void FInvite()
  178.   {
  179.   mPrintf("[%s]\n ", FloorTab[thisFloor].FlName);
  180.   getList(UserToFloor, "Invited users", NAMESIZE, FALSE);
  181.  
  182.   }
  183. static char YesInvite = TRUE;
  184. /*
  185. * FWithdraw()
  186. *
  187. * This function will withdraw invitations from a floor.
  188. */
  189. void FWithdraw()
  190.   {
  191.   mPrintf("[%s]\n ", FloorTab[thisFloor].FlName);
  192.   YesInvite = FALSE;
  193.   getList(UserToFloor, "Kicked out users", NAMESIZE, FALSE);
  194.   YesInvite = TRUE;
  195.  
  196.   }
  197. extern logBuffer logTmp;
  198. /*
  199. * UserToFloor()
  200. *
  201. * This function will invite the named user to current floor.  This function
  202. * is used in conjunction with getList().
  203. */
  204. int UserToFloor(char *name)
  205.   {
  206.   int logNo;
  207.   int InviteUserToFloor(int r);
  208.   logNo = findPerson(name, &logTmp);
  209.   if (logNo == ERROR)
  210.     Output_Citadel_Message("NODRFD", (long)name,NULL,NULL);
  211.   else
  212.     {
  213.     FloorRunner(thisRoom, InviteUserToFloor);
  214.     putLog(&logTmp, logNo);
  215.  
  216.     }
  217.   return TRUE;
  218.  
  219.   }
  220. /*
  221. * InviteUserToFloor()
  222. *
  223. * This function does the actual work of inviting a user.
  224. */
  225. int InviteUserToFloor(int r)
  226.   {
  227.   if (r != AIDEROOM)
  228.     {
  229.     if (YesInvite)
  230.     logTmp.lbgen[r] = (roomTab[r].rtgen << GENSHIFT) + MAXVISIT - 1;
  231.     else
  232.     logTmp.lbgen[r] = ((roomTab[r].rtgen + (MAXGEN-1)) % MAXGEN);
  233.  
  234.     }
  235.   return FALSE;
  236.  
  237.   }
  238. /*
  239. * FSkipped()
  240. *
  241. * This function will show skipped rooms and floors.
  242. */
  243. void FSkipped()
  244.   {
  245.   int rover, roomNo;
  246.   JustChecking = FALSE;
  247.   ShowNew = TRUE;
  248.   Output_Citadel_Message("SKPRMF",(long) FloorTab[thisFloor].FlName , NULL, NULL);
  249.   FloorRunner(thisRoom, SkippedNewRoom);
  250.   ShowNew = FALSE;
  251.   JustChecking = TRUE;
  252.   Output_Citadel_Message("SKPFLR", NULL, NULL, NULL);
  253.   for (rover = 1; rover < TopFloor; rover++)
  254.     {
  255.     roomNo = FirstRoom(rover);
  256.     if (FloorRunner(roomNo, SkippedNewRoom) != ERROR)
  257.       Output_Citadel_Message("FLRNNL",(long)FloorTab[rover].FlName , NULL, NULL);
  258.  
  259.     }
  260.   JustChecking = FALSE;
  261.   tableRunner(SkippedNewRoom, TRUE);
  262.  
  263.   }
  264. /*
  265. * FForget()
  266. *
  267. * This function will forget a floor.
  268. */
  269. char FForget()
  270.   {
  271.   Output_Citadel_Message("FLOORN",(long)FloorTab[roomTab[thisRoom].rtFlIndex].FlName, NULL, NULL);
  272.   if (!getYesNo("CONFRM")) return GOOD_SELECT;
  273.   FloorRunner(thisRoom, Zroom);
  274.   gotoRoom(baseRoom, 'S');
  275.   return GOOD_SELECT;
  276.  
  277.   }
  278. /*
  279. * FConfigure()
  280. *
  281. * This function will change floor configuration value.
  282. */
  283. char FConfigure()
  284.   {
  285.   FloorMode = !FloorMode;
  286.   mPrintf("%s mode\n ", (FloorMode) ? "FLOOR" : "Normal");
  287.   return GOOD_SELECT;
  288.  
  289.   }
  290. /*
  291. * FGotoSkip()
  292. *
  293. * This function will let us Skip an entire floor.
  294. */
  295. char FGotoSkip(int mode)
  296.   {
  297.   label floorName;
  298.   int   floorNo, newRoom = 0, rover;
  299.   outFlag = IMPERVIOUS;
  300.   if (mode == 'S')
  301.     {
  302.     mPrintf("[%s] goto ", FloorTab[roomTab[thisRoom].rtFlIndex].FlName);
  303.     };
  304.   if (getNormStr("", floorName, NAMESIZE, BS_VALID) == BACKED_OUT)
  305.     {
  306.     if (mode == 'S')
  307.       for (rover = 0; rover < strLen(FloorTab[roomTab[thisRoom].rtFlIndex].FlName)+7; rover++) mPrintf("\b \b");
  308.     return BACKED_OUT;
  309.     };
  310.   if (strLen(floorName) != 0)
  311.     {
  312.     if ((floorNo = FindFloor(floorName, TRUE)) == ERROR)
  313.       {
  314.       Output_Citadel_Message("NODRFD", (long)floorName,NULL, NULL);
  315.       return GOOD_SELECT;
  316.       };
  317.     if ((newRoom = FloorRunner(FirstRoom(floorNo), FindAny)) == ERROR)
  318.       {
  319.       Output_Citadel_Message("NOKNRM",(long) FloorTab[floorNo].FlName, NULL, NULL );
  320.       return GOOD_SELECT;
  321.       };
  322.     }
  323.   else
  324.     {
  325.     floorNo = thisFloor;
  326.     for (rover = 0; rover < TopFloor; rover++)
  327.     if (rover != floorNo && FloorTab[rover].FlInuse)
  328.       {
  329.       newRoom = FirstRoom(rover);
  330.       if ((newRoom = FloorRunner(newRoom, NSRoomHasNew)) != ERROR)
  331.       break;
  332.  
  333.       }
  334.     if (rover == TopFloor)    newRoom = 0;
  335.  
  336.     }
  337.   if (mode == 'S') FloorRunner(thisRoom, FSroom);
  338.   gotoRoom(roomTab[newRoom].rtname, mode);
  339.   return GOOD_SELECT;
  340.  
  341.   }
  342. /*
  343. * FindFloor()
  344. *
  345. * This function returns index for the given floor name.
  346. */
  347. int FindFloor(label name, char doPartial)
  348.   {
  349.   int rover;
  350.   for (rover = 0; rover < TopFloor; rover++)
  351.     {
  352.     if (strCmpU(name, FloorTab[rover].FlName) == SAMESTRING &&
  353.     FloorTab[rover].FlInuse)
  354.       {
  355.       return rover;
  356.  
  357.       }
  358.  
  359.     }
  360.   if (doPartial)
  361.   for (rover = 0; rover < TopFloor; rover++)
  362.     {
  363.     if (FloorTab[rover].FlInuse &&
  364.     matchString(FloorTab[rover].FlName, name,
  365.     lbyte(FloorTab[rover].FlName)) != NULL)
  366.     return rover;
  367.  
  368.     }
  369.   return ERROR;
  370.  
  371.   }
  372. /*
  373. * FAide()
  374. *
  375. * This function handles the floor-oriented aide commands.
  376. */
  377. char FAide()
  378.   {
  379.   char *FloorAideOpts[] =
  380.     {
  381.     "Create Floor\n", "Delete empty floors\n", "Move rooms\n",
  382.     "Kill Floor\n", "Rename Floor\n", "Floor moderator\n",
  383.     "Invite users to floor", "Withdraw users from floor", "\b", ""
  384.  
  385.     };
  386.   if (!aide)
  387.     {
  388.     if (loggedIn && strCmpU(logBuf.lbname, FloorTab[thisFloor].FlModerator) ==
  389.     SAMESTRING)
  390.       {
  391.       RenameFloor();
  392.       return GOOD_SELECT;
  393.  
  394.       }
  395.     else
  396.     return BAD_SELECT;    /* Indicates problem */
  397.  
  398.     }
  399.   RegisterThisMenu("aideflr.mnu", FloorAideOpts);
  400.   switch (GetMenuChar())
  401.     {
  402.     case 'C': CreateFloor();      break;
  403.     case 'D': DeleteFloors();     break;
  404.     case 'M': MoveRooms();        break;
  405.     case 'K': KillFloor();        break;
  406.     case 'R': RenameFloor();      break;
  407.     case 'F': FlModerator();      break;
  408.     case 'I': FInvite();        break;
  409.     case 'W': FWithdraw();        break;
  410.     case '\b': return BACKED_OUT;
  411.  
  412.     }
  413.   return GOOD_SELECT;
  414.  
  415.   }
  416. /*
  417. * FlModerator()
  418. *
  419. * This function handles the floor moderator.
  420. */
  421. void FlModerator()
  422.   {
  423.   label buffer;
  424.   if (WhoIsModerator(buffer))
  425.     {
  426.     strCpy(FloorTab[thisFloor].FlModerator, buffer);
  427.     putFloor(thisFloor);
  428.     ZeroMsgBuffer(&msgBuf);
  429.     sPrintf(msgBuf.mbtext, "%s's moderator set to %s by %s.",
  430.     FloorTab[thisFloor].FlName, buffer, logBuf.lbname);
  431.     aideMessage(NULL,FALSE);
  432.  
  433.     }
  434.  
  435.   }
  436. /*
  437. * DeleteFloors()
  438. *
  439. * This function deletes empty floors.
  440. */
  441. void DeleteFloors()
  442.   {
  443.   int rover, count = 0;
  444.   ZeroMsgBuffer(&msgBuf);
  445.   sPrintf(msgBuf.mbtext, "Following empty floors deleted by %s: ",
  446.   logBuf.lbname);
  447.   for (rover = 1; rover < TopFloor; rover++)
  448.     {
  449.     if (FloorTab[rover].FlInuse)
  450.       {
  451.       if (FirstRoom(rover) == ERROR)
  452.         {
  453.         count++;
  454.         FloorTab[rover].FlInuse = FALSE;
  455.         putFloor(rover);
  456.         sPrintf(lbyte(msgBuf.mbtext), "[%s], ", FloorTab[rover].FlName);
  457.  
  458.         }
  459.  
  460.       }
  461.  
  462.     }
  463.   if (count)
  464.     {
  465.     *(lbyte(msgBuf.mbtext) - 2) = '.';
  466.     *(lbyte(msgBuf.mbtext) - 1) = 0;
  467.  
  468.     }
  469.   aideMessage(NULL,FALSE);
  470.  
  471.   }
  472. /*
  473. * MoveRooms()
  474. *
  475. * This function moves a series of rooms into the current floor.
  476. */
  477. void MoveRooms()
  478.   {
  479.   int   CurrentRoom;
  480.   char  *end;
  481.   CurrentRoom = thisRoom;
  482.   GlobalFloor = thisFloor;
  483.   MoveCount = 0;
  484.   ZeroMsgBuffer(&msgBuf);
  485.   sPrintf(msgBuf.mbtext, "Following rooms moved to floor %s by %s: ",
  486.   FloorTab[thisFloor].FlName, logBuf.lbname);
  487.   getList(MoveToFloor, "Rooms to move to this floor", NAMESIZE, FALSE);
  488.   getRoom(CurrentRoom);       /* MoveToFloor changes thisRoom & roomBuf */
  489.   if (MoveCount != 0)
  490.     {
  491.     end = lbyte(msgBuf.mbtext);
  492.     *(end - 2) = '.';
  493.     *(end - 1) = 0;
  494.     aideMessage(NULL,FALSE);
  495.  
  496.     }
  497.  
  498.   }
  499. /*
  500. * MoveToFloor()
  501. *
  502. * This function will move a single room to a floor.
  503. */
  504. int MoveToFloor(char *name)
  505.   {
  506.   int roomNo;
  507.   if ((roomNo = roomExists(name)) == ERROR)
  508.     {
  509.     Output_Citadel_Message("NOROOM",(long)name,NULL,NULL);
  510.     return TRUE;
  511.  
  512.     }
  513.   if (   roomNo == LOBBY  ||  roomNo == MAILROOM  ||  roomNo == AIDEROOM  )
  514.     {
  515.     if (!getYesNo("WRMVSP")) return TRUE;
  516.  
  517.     }
  518.   MoveCount++;
  519.   getRoom(roomNo);
  520.   roomBuf.rbFlIndex = GlobalFloor;
  521.   putRoom(roomNo);
  522.   noteRoom();
  523.   sPrintf(lbyte(msgBuf.mbtext), "%s, ", formRoom(thisRoom, FALSE, FALSE));
  524.   return TRUE;
  525.  
  526.   }
  527. /*
  528. * RenameFloor()
  529. *
  530. * This function renames a floor.
  531. */
  532. void RenameFloor()
  533.   {
  534.   label FloorName;
  535.   int   ReturnNo;
  536.   if (thisFloor == 0)
  537.     {
  538.     Output_Citadel_Message("USECFG",NULL ,NULL,NULL);
  539.     return ;
  540.  
  541.     }
  542.   if (!getXString("FLRNIT", FloorName, NAMESIZE, NULL, NULL))
  543.   return ;
  544.   if ((ReturnNo = FindFloor(FloorName, FALSE)) != ERROR)
  545.     {
  546.     if (ReturnNo != thisFloor)
  547.       {
  548.       Output_Citadel_Message("ALRYFR",(long)FloorName,NULL,NULL);
  549.       return;
  550.  
  551.       }
  552.  
  553.     }
  554.   ZeroMsgBuffer(&msgBuf);
  555.   sPrintf(msgBuf.mbtext, "The floor %s renamed to %s by %s.",
  556.   FloorTab[thisFloor].FlName, FloorName, logBuf.lbname);
  557.   strCpy(FloorTab[thisFloor].FlName, FloorName);
  558.   putFloor(thisFloor);
  559.   aideMessage(NULL,FALSE);
  560.  
  561.   }
  562. /*
  563. * CreateFloor()
  564. *
  565. * This function creates a floor.
  566. */
  567. void CreateFloor()
  568.   {
  569.   label FloorName;
  570.   int   rover;
  571.   if (  thisRoom == LOBBY ||
  572.   thisRoom == MAILROOM ||
  573.   thisRoom == AIDEROOM  )
  574.     {
  575.     Output_Citadel_Message("CCRFLR",NULL, NULL, NULL);
  576.     return ;
  577.  
  578.     }
  579.   if (!getXString("FLRNIT", FloorName, NAMESIZE, NULL, NULL))
  580.   return ;
  581.   if (FindFloor(FloorName, FALSE) != ERROR)
  582.     {
  583.     Output_Citadel_Message("ALRYFR",(long)FloorName,NULL,NULL);
  584.     return;
  585.  
  586.     }
  587.   for (rover = 1; rover < TopFloor; rover++)
  588.   if (!FloorTab[rover].FlInuse) break;
  589.   if (rover == TopFloor)
  590.     {
  591.     FloorTab = (struct floor *) realloc(FloorTab,
  592.     sizeof *FloorTab * ++TopFloor);
  593.  
  594.     }
  595.   roomBuf.rbFlIndex = rover;
  596.   FloorTab[rover].FlInuse = TRUE;
  597.   strCpy(FloorTab[rover].FlName, FloorName);
  598.   memset(FloorTab[rover].FlModerator, '\0',sizeof(label));
  599.   putFloor(rover);
  600.   putRoom(thisRoom);
  601.   noteRoom();
  602.   ZeroMsgBuffer(&msgBuf);
  603.   sPrintf(msgBuf.mbtext, "The floor %s created by %s.", FloorName,
  604.   logBuf.lbname);
  605.   aideMessage(NULL,FALSE);
  606.  
  607.   }
  608. /*
  609. * putFloor()
  610. *
  611. * This will put a floor record out to disk.
  612. */
  613. void putFloor(int i)
  614.   {
  615.   SYS_FILE name;
  616.   FILE *fd;
  617.   long r;
  618.   extern char *R_W_ANY;
  619.   makeSysName(name, "ctdlflr.sys", &cfg.floorArea);
  620.   if ((fd = safeopen(name, R_W_ANY)) == NULL)
  621.   crashout("Couldn't open the floor file for update!");
  622.   r = i * sizeof *FloorTab;
  623.   fseek(fd, r, 0);
  624.   if (fwrite(FloorTab + i, sizeof *FloorTab, 1, fd) != 1)
  625.   crashout("?putFloor(): write failed!");
  626.   fclose(fd);
  627.  
  628.   }
  629. /*
  630. * KillFloor()
  631. *
  632. * This function kills a floor.
  633. */
  634. void KillFloor()
  635.   {
  636.   int CurrentFloor, CurrentRoom;
  637.   if (roomBuf.rbFlIndex == 0)
  638.     {
  639.     Output_Citadel_Message("NOKILF",NULL ,NULL,NULL);
  640.     return;
  641.  
  642.     }
  643.   if (!getYesNo("CONFRM")) return;
  644.   ZeroMsgBuffer(&msgBuf);
  645.   sPrintf(msgBuf.mbtext, "Floor %s killed by %s.",
  646.   FloorTab[thisFloor].FlName, logBuf.lbname);
  647.   aideMessage(NULL,FALSE);
  648.   CurrentFloor = thisFloor;   /* #define in CTDL.H */
  649.   CurrentRoom  = thisRoom;
  650.   maim = getYesNo("MVALLM");
  651.   FloorRunner(thisRoom, MaimOrKill);
  652.   FloorTab[CurrentFloor].FlInuse = FALSE;
  653.   putFloor(CurrentFloor);
  654.   /* due to behavior of MaimOrKill */
  655.   getRoom((!maim) ? LOBBY : CurrentRoom);
  656.  
  657.   }
  658. /*
  659. * MaimOrKill()
  660. *
  661. * This will kill or move a room to the main floor.
  662. */
  663. int MaimOrKill(int i)
  664.   {
  665.   getRoom(i);
  666.   if (maim)
  667.     {
  668.     roomBuf.rbFlIndex = 0;
  669.  
  670.     }
  671.   else
  672.     {
  673.     roomBuf.rbflags.INUSE = FALSE;
  674.  
  675.     }
  676.   putRoom(i);
  677.   noteRoom();
  678.   return FALSE;
  679.  
  680.   }
  681. /*
  682. * FKnown()
  683. *
  684. * This function will handle the ticklish task of floor display.
  685. */
  686. char FKnown(char mode)
  687.   {
  688.   int         rover, roomNo;
  689.   extern int  DirAlign;
  690.   extern char AlignChar;
  691.   switch (mode)
  692.     {
  693.     case FORGOTTEN:
  694.       Output_Citadel_Message("FORGFL",NULL,NULL,NULL);
  695.     ShowNew = 2;
  696.     SelNew = TRUE;
  697.     RunDisplay();
  698.     SelNew = FALSE;
  699.     break;
  700.     case INT_NOVICE:
  701.     case INT_EXPERT:
  702.     case NOT_INTRO:
  703.     if (SelNew)
  704.       Output_Citadel_Message("RMUNRF",(long)FloorTab[thisFloor].FlName,NULL,NULL);
  705.     ShowNew = TRUE;
  706.     FloorRunner(thisRoom, DispRoom);
  707.     if (mode == INT_NOVICE || mode == NOT_INTRO)
  708.       {
  709.       Output_Citadel_Message("NOUNSN",NULL,NULL,NULL);
  710.       ShowNew = FALSE;
  711.       FloorRunner(thisRoom, DispRoom);
  712.  
  713.       }
  714.     if (SelNew)
  715.       {
  716.       Output_Citadel_Message("OTFLUM",NULL,NULL,NULL);
  717.       for (rover = 0; rover < TopFloor; rover++)
  718.         {
  719.         if (rover != roomBuf.rbFlIndex)
  720.           {
  721.           roomNo = FirstRoom(rover);
  722.           if (FloorRunner(roomNo, RoomHasNew) != ERROR)
  723.             Output_Citadel_Message("FLRNNL", (long)FloorTab[rover].FlName,NULL,NULL);
  724.  
  725.           }
  726.  
  727.         }
  728.  
  729.       }
  730.     break;
  731.     case ARCH_SEL:
  732.     case DR_SEL:
  733.     case SH_SEL:
  734.     case PR_SEL:
  735.     case ANON_SEL:
  736.     case READONLY:
  737.     RunDisplay();
  738.     break;
  739.     default:
  740.     SelNew = TRUE;
  741.     doCR();
  742.     Output_Citadel_Message("FLRWUR", NULL,NULL,NULL);
  743.     ShowNew = FoundNew = TRUE;
  744.     RunDisplay();
  745.     doCR();
  746.     Output_Citadel_Message("FLRWNR", NULL,NULL,NULL);
  747.     ShowNew = FoundNew = FALSE;
  748.     RunDisplay();
  749.     SelNew = FALSE;
  750.  
  751.     }
  752.   return GOOD_SELECT;
  753.  
  754.   }
  755. /*
  756. * RunDisplay()
  757. *
  758. * This will do the actual work of displaying in Floor mode.
  759. */
  760. void RunDisplay()
  761.   {
  762.   extern int  DirAlign;
  763.   extern char AlignChar;
  764.   int rover, roomNo;
  765.   AlignChar = ' ';
  766.   for (rover = 0; rover < TopFloor; rover++)
  767.     {
  768.     if (FloorTab[rover].FlInuse)
  769.       {
  770.       roomNo = FirstRoom(rover);
  771.       if (FloorRunner(roomNo, CheckFloor) != ERROR)
  772.         {
  773.         DispFloorName(rover);
  774.         FloorRunner(roomNo, DispRoom);
  775.         DirAlign = 0;
  776.  
  777.         }
  778.  
  779.       }
  780.  
  781.     }
  782.  
  783.   }
  784. /*
  785. * DispFloorName()
  786. *
  787. * This function displays a floor name with periods, etc...
  788. */
  789. void DispFloorName(int FloorNo)
  790.   {
  791.   int i;
  792.   extern int DirAlign;
  793.   extern char AlignChar;
  794.   Output_Citadel_Message("FLRSNL", (long)FloorTab[FloorNo].FlName,NULL,NULL);
  795.   if (termWidth >= 50)
  796.     {
  797.     DirAlign = 24;
  798.     AlignChar = ' ';
  799.     for (i = strLen(FloorTab[FloorNo].FlName); i < 21; i++)
  800.     mPrintf(".");
  801.  
  802.     }
  803.   else mPrintf("-");
  804.  
  805.   }
  806. /*
  807. * These functions are used as arguments to FloorRunner
  808. */
  809. /*
  810. * RoomHasNew()
  811. *
  812. * This returns TRUE if room has new messages for the current user.
  813. */
  814. int RoomHasNew(int i)
  815.   {
  816.   return (    roomTab[i].rtlastMessage >
  817.   logBuf.lbvisit[logBuf.lbgen[i] & CALLMASK] &&
  818.   roomTab[i].rtlastMessage >= cfg.oldest     );
  819.  
  820.   }
  821. /*
  822. * CheckFloor()
  823. *
  824. * This multipurpose function returns true of one of the combinations is
  825. * true.
  826. */
  827. int CheckFloor(int i)
  828.   {
  829.   #ifdef OLD_STYLE
  830.   if (( SelDirs   &&   roomTab[i].rtflags.ISDIR   ) ||
  831.   ( SelShared &&   roomTab[i].rtflags.SHARED  ) ||
  832.   ( SelPriv   &&   !roomTab[i].rtflags.PUBLIC ) ||
  833.   ( SelArch   &&   roomTab[i].rtflags.ARCHIVE ) ||
  834.   ( SelAnon   &&   roomTab[i].rtflags.ANON )    ||
  835.   ( SelRO     &&   roomTab[i].rtflags.READ_ONLY )    ||
  836.   ( SelNew && (ShowNew == 2 || (RoomHasNew(i) && FoundNew) ||
  837.   (!RoomHasNew(i) && !FoundNew))))
  838.   return TRUE;
  839.   #else
  840.   if (FlagCheck(i) ||
  841.   ( SelNew && (ShowNew == 2 || (RoomHasNew(i) && FoundNew) ||
  842.   (!RoomHasNew(i) && !FoundNew))))
  843.   return TRUE;
  844.   #endif
  845.   return FALSE;
  846.  
  847.   }
  848. /*
  849. * NSRoomHasNew()
  850. *
  851. * TRUE if room has new messages and isn't skipped.
  852. */
  853. int NSRoomHasNew(int i)
  854.   {
  855.   if (!roomTab[i].rtflags.SKIP && RoomHasNew(i))
  856.   return TRUE;
  857.   if (roomTab[i].rtflags.SKIP) /* Kludge this in -- ugly but useful */
  858.   HasSkipped = TRUE;
  859.   return FALSE;
  860.  
  861.   }
  862. /*
  863. * DispRoom()
  864. *
  865. * This function will display a room name.
  866. */
  867. int DispRoom(int i)
  868.   {
  869.   char HasNew;
  870.   extern char shownHidden;
  871.   HasNew = RoomHasNew(i);
  872.   if (FlagCheck(i) ||
  873.   ( SelNew &&
  874.   (ShowNew == 2 || (HasNew && ShowNew == 1) ||
  875.   (!HasNew && !ShowNew))))
  876.     {
  877.     Output_Citadel_Message("DISPRM",(long)formRoom(i, TRUE, TRUE),NULL,NULL);
  878.     if (!roomTab[i].rtflags.PUBLIC) shownHidden = TRUE;
  879.     if (SelDirs && HalfSysop())
  880.       {
  881.       if (FindDirName(i) != NULL)
  882.         Output_Citadel_Message("DISPDR",(long)FindDirName(i),NULL,NULL);
  883.       else
  884.         Output_Citadel_Message("DISPNF",NULL,NULL,NULL);
  885.  
  886.       }
  887.  
  888.     }
  889.   return FALSE;
  890.  
  891.   }
  892. /*
  893. * Zroom()
  894. *
  895. * This lets us Zforget a room.  Used for ;Z.
  896. */
  897. int Zroom(int i)
  898.   {
  899.   int r;
  900.   if (     i == LOBBY    ||
  901.   i == MAILROOM ||
  902.   i == AIDEROOM      )
  903.     {
  904.     return FALSE;
  905.  
  906.     }
  907.   r = (roomTab[i].rtgen + FORGET_OFFSET) % MAXGEN;
  908.   logBuf.lbgen[i] = r << GENSHIFT;
  909.   return FALSE;
  910.  
  911.   }
  912. /*
  913. * FSroom()
  914. *
  915. * This will skip a room on a floor.
  916. */
  917. int FSroom(int i)
  918.   {
  919.   roomTab[i].rtflags.SKIP = 1;     /* Set bit */
  920.   return FALSE;
  921.  
  922.   }
  923. /*
  924. * FindAny()
  925. *
  926. * This finds any known room on a floor.
  927. */
  928. int FindAny(int i)
  929.   {
  930.   return TRUE;        /* My, that was easy... */
  931.  
  932.   }
  933. static int FlagCheck(int i)
  934.   {
  935.   if (( SelDirs   &&   roomTab[i].rtflags.ISDIR   ) ||
  936.   ( SelShared &&   roomTab[i].rtflags.SHARED  ) ||
  937.   ( SelPriv   &&   !roomTab[i].rtflags.PUBLIC ) ||
  938.   ( SelAnon   &&   roomTab[i].rtflags.ANON )    ||
  939.   ( SelArch   &&   roomTab[i].rtflags.ARCHIVE ) ||
  940.   ( SelRO     &&   roomTab[i].rtflags.READ_ONLY ))
  941.   return TRUE;
  942.   return FALSE;
  943.  
  944.   }
  945.